<template>
  <view class="wrap-box" v-for="(item, index) in state.list" :key="index">
    <!-- <view class="wrap" v-if="index != 0 && index != 1"> -->
    <view class="wrap">
      <view class="answer">
        {{ item.text }}
      </view>
      <view class="answer" v-if="item.textZh" style="margin-top: 20rpx">
        {{ item.textZh }}
      </view>
      <view class="bottom-bar">
        <!-- <view class="left" @tap.stop="onPlayMP3(item, index)">
          <image src="@/static/imgs/sound@2x.png" mode="widthFix"></image>
        </view> -->
        <view></view>
        <view class="right">
          <image
            src="@/static/imgs/icons/mic.png"
            mode="widthFix"
            @touchstart.stop="startRecord(item, index)"
            @touchend.stop="endRecord(item, index)"
          ></image>
          <image
            src="@/static/imgs/icons/sound@2x.png"
            mode="widthFix"
            @tap.stop="onPlayMP3(item, index)"
          ></image>
          <image
            src="@/static/imgs/icons/fanyi_icon.png"
            mode="widthFix"
            @tap.stop="onTranslate(index)"
          ></image>
          <image
            src="@/static/imgs/icons/file-copy@2x.png"
            mode="widthFix"
            @tap.stop="onCopyIconClick(index)"
          >
          </image>
        </view>
      </view>
    </view>
    <view class="result-wrap" v-if="item.isShowResult">
      <view class="img-box">
        <image
          src="@/static/imgs/sound@2x.png"
          mode="widthFix"
          @tap.stop="onPlayIconClick(index, item.result)"
        ></image>
      </view>
      <view class="comment-box">
        <view class="result-bar"> {{ item.result }} </view>
        <view class="comment-bar">
          <text v-if="!item.isShowComment">分值计算中...</text>
          <TnRate
            v-if="item.isShowComment"
            v-model="item.rateValue"
            active-color="#FAC909"
            :min="0"
            :max="5"
            allow-half
            :readonly="true"
            style="float: right; margin-top: 18rpx"
          />
        </view>
      </view>
    </view>
  </view>

  <!-- 语音音阶动画 长按说话时的动画 -->
  <view class="prompt" v-if="animation">
    <section class="dots-container">
      <view class="dot"></view>
      <view class="dot"></view>
      <view class="dot"></view>
      <view class="dot"></view>
      <view class="dot"></view>
    </section>
    <text>说话中...</text>
  </view>
</template>

<script lang="ts" setup>
import { ref, reactive } from 'vue'
import { tnNavPage } from '@tuniao/tnui-vue3-uniapp/utils'
import { bottomEnter } from '@/components/bottom-enter'
import { onLoad, onHide, onUnload } from '@dcloudio/uni-app'
import { getChat } from '@/services/api'
import { useScrollUpdownBottomContent, useWebsocket } from '@/hooks'
import { Base64 } from 'js-base64'
import number from '@tuniao/tnui-vue3-uniapp/libs/async-validator/validator/number'
var plugin = requirePlugin('WechatSI')
let manager = plugin.getRecordRecognitionManager()
// 获取录音
const recorderManager = uni.getRecorderManager()
let innerAudioContext = uni.createInnerAudioContext()
const audioData = ref([])
const allAudioData = ref([])
innerAudioContext.autoplay = true
const showPopup = ref(false)
const handlerInterval = ref()
const tipsList = ref([])
const tempFilePath = ref()
const uploadChunkReceived = ref()
const {
  connectWebSocketComment,
  connectWebSocket,
  APPID,
  toBase64,
  handlePlayVideo,
  textTranslate,
  webSocketSendComment,
  webSocketSend,
  base64toJson,
  handleClickVideo,
  webSocketSendMp3,
  handleCloseVideo,
  splitText,
} = useWebsocket()
const problem = ref('')
const answer = ref('')
const audioSrc = ref('')
const rateValue = ref(1)
const testAudioUrl = ref('')
const state = reactive({
  list: [],
  audioDataList: [],
  currentItem: {},
})
const currentIndex = ref(0)
const animation = ref(false)
const messages = ref([
  { content: '请输入您的问题或需求，我随时帮你解答', type: 'system' },
])
const messagesBack = ref([
  { content: '请输入您的问题或需求，我随时帮你解答', role: 'system' },
])
//此数组用于推荐问题
const chatArr = reactive({
  messages: [
    {
      role: 'assistant',
      content: '请输入您的问题或需求，我随时帮你解答',
    },
  ],
})
const page = ref() //1:话题演讲，2：场景练习
let music = uni.createInnerAudioContext()
onLoad((option) => {
  const { source, answerEn } = option
  let newData = base64toJson(answerEn)
  page.value = option?.source == 1 ? 1 : 2
  if (source == 1) {
    let text = newData
    initSubsection(text)
  }
  if (source == 2) {
    music.src = option?.audio
    music.obeyMuteSwitch = false
    const analysisTxt = JSON.parse(newData)
    state.list = analysisTxt.map((item) => {
      return {
        ...item,
        isShowResult: false,
        result: '',
        rateValue: 0,
        isShowComment: false,
      }
    })
    // state.list = analysisTxt
  }
  // console.log(JSON.parse(option.answerEn))
  startWatch()

  // const analysisTxt = JSON.parse(option.answerEn)
  // console.log(analysisTxt)
  // console.log(66666666666666666666666666)
  // // answer.value = analysisTxt
  // state.list = analysisTxt
  // initSubsection(analysisTxt)
  // outputText(answer.value)
  // const analysisTxt = base64toJson(option.answerEn)
  // if (option.answerEn) {
  //   sendMessage(
  //     `请把以下英语段落切分为多个英文句子:${analysisTxt}，除了英文句子不要回复其他无关内容给我`
  //   )
  //   answer.value = analysisTxt
  //   state.list = splitTextByParagraph(analysisTxt)
  //   outputText(answer.value)
  // }
  // initRecord()
})
const isPlayingIndex = ref(-1)
const onPlayMP3 = (item, index) => {
  if (page.value == 2) {
    if (isPlayingIndex.value == index) {
      music.stop()
      isPlayingIndex.value = -1
      // music.onPlay(() => {
      //   music.pause()
      //   return 0
      // })
      // music.onPause(() => {
      //   music.play() //执行播放
      //   return 0
      // })
    } else {
      music.stop()
      handleCloseVideo()
      // music.seek(item.startSeconds)
      music.startTime = item.startSeconds
      music.buffered = item.startSeconds
      music.obeyMuteSwitch = false
      music.play() //执行播放
      music.onPlay(() => {
        isPlayingIndex.value = index
      })
      music.onTimeUpdate(() => {
        console.log('2121')
        if (item.endSeconds < music.currentTime) {
          music.stop()
        }
        console.log(music.currentTime)
      })
      music.onEnded(() => {
        //播放结束
        music.stop()
        isPlayingIndex.value = -1
        console.log('播放结束')
      })
    }
  } else {
    onPlayIconClick(index, item.text)
  }
}
onHide(() => {
  music.stop()
  stopAudio()
})

onUnload(() => {
  music.stop()
  stopAudio()
  handleCloseVideo()
})

// 分段
const initSubsection = (analysisTxt) => {
  let arr = splitText(analysisTxt)
  state.list = arr
    .filter((item) => item.type == 'Sentence')
    .map((item) => {
      return {
        text: item.raw,
        isShowResult: false,
        result: '',
        rateValue: 0,
        isShowComment: false,
      }
    })
}
// const startRecord = async (item, index) => {
//   try {
//     console.log('sdhcdbcdjncdkmckl/dmfm l.mk/md;.', item)
//     currentIndex.value = index
//     state.currentItem = item
//     animation.value = true
//     console.log('1111', item)
//     const res = await connectWebSocket()
//     if (res != '') {
//       console.log('2222', res)
//       state.list[currentIndex.value].result = res
//       state.list[currentIndex.value].isShowResult = true
//     } else {
//       console.log('3333', res)
//       state.list[currentIndex.value].isShowResult = false
//       uni.showToast({
//         title: '未识别到文字',
//         icon: 'none',
//       })
//     }
//     // 评分
//     const data = await connectWebSocketComment(state.currentItem.text)
//     try {
//       console.log('4444', data)
//       state.list[currentIndex.value].isShowComment = true
//       state.list[currentIndex.value].rateValue = Number(data.total_score)
//     } catch (err) {
//       console.log('5555', err)
//       state.list[currentIndex.value].isShowComment = false
//       state.list[currentIndex.value].rateValue = 0
//       // state.list[currentIndex.value].isShowResult = false
//       // uni.showToast({
//       // 	title: '识别失败',
//       // 	icon: 'none'
//       // })
//     }

//     console.log('6666')
//     recorderManager.start({
//       duration: 30000, // 600000（10 分钟）,默认值 60000（1 分钟）
//       numberOfChannels: 1, // 录音通道数，有效值 1/2
//       frameSize: 1,
//       format: 'pcm', // 音频格式
//       sampleRate: 16000, // 采样率
//     })
//     console.log('7777')
//   } catch (e) {
//     console.log('错误了', e)
//   }

//   // state.list[currentIndex.value].isShowResult = true
//   // 常规
// }

// 长按录制
const startRecord = (item, index) => {
  try {
    console.log('sdhcdbcdjncdkmckl/dmfm l.mk/md;.', item)
    currentIndex.value = index
    state.currentItem = item
    animation.value = true
    console.log('1111', item)
    connectWebSocket().then((res) => {
      if (res != '') {
        console.log('2222', res)
        state.list[currentIndex.value].result = res
        state.list[currentIndex.value].isShowResult = true
      } else {
        console.log('3333', res)
        state.list[currentIndex.value].isShowResult = false
        uni.showToast({
          title: '未识别到文字',
          icon: 'none',
        })
      }
    })
    // 评分
    connectWebSocketComment(state.currentItem.text)
      .then((res) => {
        console.log('4444', res)
        state.list[currentIndex.value].isShowComment = true
        state.list[currentIndex.value].rateValue = Number(res.total_score)
        console.log(state.list)
      })
      .catch((err) => {
        console.log('5555', err)
        state.list[currentIndex.value].isShowComment = false
        state.list[currentIndex.value].rateValue = 0
        console.log(state.list)
        // state.list[currentIndex.value].isShowResult = false
        // uni.showToast({
        // 	title: '识别失败',
        // 	icon: 'none'
        // })
      })
    console.log('6666')
    recorderManager.start({
      duration: 30000, // 600000（10 分钟）,默认值 60000（1 分钟）
      numberOfChannels: 1, // 录音通道数，有效值 1/2
      frameSize: 1,
      format: 'pcm', // 音频格式
      sampleRate: 16000, // 采样率
    })
    console.log('7777')
  } catch (e) {
    console.log('错误了', e)
  }

  // state.list[currentIndex.value].isShowResult = true
  // 常规
}

// 松开停止
const endRecord = (item, index) => {
  console.log(animation, 'animationanimationanimation')
  state.currentItem = item
  currentIndex.value = index
  recorderManager.stop()
  animation.value = false
}

const startWatch = () => {
  var lastFrame = []
  recorderManager.onStop(function (res) {
    console.log('6666', lastFrame)
    // 监听最后一帧
    // 基础
    webSocketSend(lastFrame, true).then((res) => {
      if (res == 'success') {
      }
    })
    webSocketSendComment(lastFrame, state.currentItem.text, true).then(
      (res) => {
        if (res == 'success') {
        }
      }
    )

    console.log('8888', res)
    let tempFile = res.tempFilePath //音频文件地址
    tempFilePath.value = tempFile
    // #ifdef MP-WEIXIN
    const fs = uni.getFileSystemManager()
    // 评分
    fs.readFile({
      //读取文件并转为ArrayBuffer
      filePath: tempFile,
      success(res) {},
    })
    // #endif
  })
  recorderManager.onFrameRecorded(function (res) {
    console.log('9999', res)
    const { frameBuffer, isLastFrame } = res
    lastFrame = frameBuffer
    let newFrameBuffer = Array.from(new Uint8Array(frameBuffer))
    // 基础
    webSocketSend(frameBuffer, isLastFrame).then((res) => {
      if (res == 'success') {
      }
    })
    // 评分
    webSocketSendComment(frameBuffer, state.currentItem.text, isLastFrame).then(
      (res) => {
        if (res == 'success') {
        }
      }
    )
  })
}

// 利用ai接口
// const sendMessage = (context) => {
//   if (messages.value.length == 1) {
//     messages.value = []
//   }
//   if (context.trim() !== '') {
//     messages.value.push({ content: context, role: 'user' })
//     messagesBack.value.push({ content: context, role: 'user' })
//     chatArr.messages.push({ content: context, role: 'user' })
//     let data = {
//       messages: messagesBack.value,
//     }
//     const requestTask = uni.request({
//       url: 'https://sj.xming-ai.com/enteacher/aichat',
//       timeout: 15000,
//       responseType: 'text',
//       method: 'POST',
//       enableChunked: true,
//       data: data,
//       success: (response) => {
//         console.log(response)
//       },
//       fail: (error) => {},
//     })
//     requestTask.onHeadersReceived(function (res) {
//       console.log(res.header)
//     })

//     // 这里监听消息
//     requestTask.onChunkReceived(function (res) {
//       let decoder = new TextDecoder('utf-8')
//       let text = decoder.decode(new Uint8Array(res.data))
//     })

//     requestTask.onChunkReceived(function (res) {
//       const uint8Array = new Uint8Array(res.data)
//       let text = String.fromCharCode.apply(null, uint8Array)
//       text = decodeURIComponent(escape(text))
//       console.log(text)
//       let arr = text.split('\n')
//       let new_arr = arr[3]
//       let data = JSON.parse(new_arr.slice(5)).output.text
//       messagesBack.value.push({
//         role: 'assistant',
//         content: data,
//       })
//       chatArr.messages.push({ content: data, role: 'assistant' })
//       // answer.value = data
//       // outputText(answer.value)
//       let linesArray = data.split('\n')
//       state.list = linesArray.map((item) => {
//         return {
//           text: item,
//           isShowResult: false,
//           result: '',
//           rateValue: 0,
//           isShowComment: false,
//         }
//       })
//       console.log(777)
//       console.log(state.list)
//     })
//   }
// }

// /**
//  * 将给定的文本按照300字并且按照句号分为多个p标签
//  *
//  * @param text 给定的文本
//  * @returns 返回分割后的多个p标签的数组
//  */
// const splitTextByParagraph = (text) => {
//   // 将文本按照句号分割成多个句子
//   const sentences = text.split('.')

//   // 初始化一个空数组来存储生成的p标签
//   const paragraphs = []

//   // 遍历每个句子
//   for (let i = 0; i < sentences.length; i++) {
//     // 将当前句子和前面未完成的句子合并成一个p标签
//     const paragraph = sentences.slice(i, i + 300).join('.')

//     // 将生成的p标签添加到数组中
//     paragraphs.push({
//       text: paragraph,
//       isShowResult: false,
//       result: '',
//     })
//   }
//   console.log(666666)
//   console.log(paragraphs)
//   // 返回生成的p标签数组
//   return paragraphs
// }

// 流式输出文字
const outputText = (text) => {
  var index = 0
  const streamOutput = () => {
    if (index < text.length) {
      var currentText = text.substring(0, index + 1)
      answer.value = currentText
      index++
    } else {
      clearInterval(timer)
    }
  }
  let timer = setInterval(streamOutput, 20)
}

//英文翻译成中文
const onTranslate = (index) => {
  currentIndex.value = index
  plugin.translate({
    lfrom: 'en_US',
    lto: 'zh_CN',
    content: state.list[currentIndex.value].text,
    success: function (res) {
      if (res.retcode == 0) {
        console.log('result', res.result)
        // answer.value = res.result
        // outputText(answer.value)
        state.list[currentIndex.value].textZh = res.result
        outputText(res.result)
      } else {
        console.warn('翻译失败', res)
      }
    },
    fail: function (res) {
      console.log('网络失败', res)
    },
  })
}

//中文转语音
// const textToSpeech = () => {
//   console.log(state.list[currentIndex.value].text)

//   return new Promise((resolve, reject) => {
//     plugin.textToSpeech({
//       lang: 'zh_CN',
//       tts: true,
//       content: state.list[currentIndex.value].text,
//       success: function (res) {
//         console.log('succ tts', res.filename)
//         audioSrc.value = res.filename
//         resolve()
//       },
//       fail: function (res) {
//         console.log('fail tts', res)
//       },
//     })
//   })
// }
//英文转语音
const textToSpeech = () => {
  console.log(state.list[currentIndex.value].text)
  return new Promise((resolve, reject) => {
    plugin.textToSpeech({
      lang: 'en_US',
      tts: true,
      content: state.list[currentIndex.value].text,
      success: function (res) {
        console.log('succ tts', res.filename)
        audioSrc.value = res.filename
        resolve()
      },
      fail: function (res) {
        console.log('fail tts', res)
      },
    })
  })
}

const stopAudio = () => {
  innerAudioContext.stop()
}

const onPlayIconClick = (index, text) => {
  music.stop()
  isPlayingIndex.value = -1
  // Chinese中文 | English英文
  webSocketSendMp3(text, 'English').then((res) => {
    let newArr = []
    res.map((item, index) => {
      const arrayBuffer = wx.base64ToArrayBuffer(item)
      const newBuffer = new Uint8Array(arrayBuffer)
      newArr.push(...newBuffer)
    })
    let uint8Array = new Uint8Array(newArr)
    const newUrl = wx.createBufferURL(uint8Array.buffer)
    handleClickVideo(newUrl)
  })
}

// const onPlayIconClick = async (index) => {
// 	currentIndex.value = index

// 	await textToSpeech()

// 	innerAudioContext.src = audioSrc.value
// 	innerAudioContext.play()
// 	innerAudioContext.onPlay(() => {
// 		console.log('开始播放')
// 	})
// 	innerAudioContext.onError((err) => {
// 		console.log(err.errMsg)
// 	})
// 	innerAudioContext.onEnded(() => {
// 		innerAudioContext = null
// 	})
// }

const onCopyIconClick = (index) => {
  currentIndex.value = index
  console.log('4444', state.list[currentIndex.value].text)
  uni.setClipboardData({
    data: state.list[currentIndex.value].text,
    success: () => {
      console.log('success')
      uni.showToast({
        title: '复制成功',
        icon: 'none',
      })
    },
    fail: () => {
      console.log('fail')
    },
  })
}
</script>

<style lang="scss" scoped>
.problem-title {
  margin: 40rpx auto;
  text-align: center;
  font-size: 26rpx;
  font-weight: bold;
  font-family: 'tuniao-xiaowei';
}

.wrap-box {
  width: 100%;
  padding: 0 48rpx;
  margin: 10rpx 0;
}

.wrap {
  background: linear-gradient(90deg, #4b49e8 0%, #6b8bfb 100%);
  width: 100%;
  padding: 24rpx 20rpx;
  margin-bottom: 30rpx;
  border-radius: 0 30rpx 30rpx 30rpx;

  .answer {
    font-family:
      PingFang SC,
      PingFang SC;
    font-weight: 400;
    font-size: 28rpx;
    // color: #191919;
    color: #fff;
    line-height: 44rpx;
    text-align: justified;
    font-style: normal;
    text-transform: none;
  }
}

image {
  width: 50rpx;
}

.bottom-bar {
  margin-top: 16rpx;
  display: flex;
  justify-content: space-between;
  align-items: center;

  .left {
    image {
      vertical-align: middle;
      margin-right: 14rpx;
    }
  }

  .left {
    text {
      vertical-align: middle;
      color: #876fd1;
    }
  }

  .right {
    display: flex;

    button {
      background-color: #fff;
      width: 40rpx;
      margin: 0;
      padding: 0;
      position: relative;
      margin-right: 12rpx;

      image {
        position: absolute;
        top: 0;
        left: 0;
      }
    }

    image {
      margin-right: 18rpx;
    }
  }
}

.result-wrap {
  display: flex;
  justify-content: space-between;
  margin: 48rpx 0;
}

.img-box {
  width: 60rpx;
  height: 60rpx;
  background-color: #fff;
  border-radius: 50%;
  display: flex;
  align-items: center;
  justify-content: center;
}

.comment-box {
  width: 90%;
  background-color: #fff;
  border-radius: 16rpx;
  margin-left: 20rpx;
  padding: 24rpx;
  background: linear-gradient(
    135deg,
    #ffffff 0%,
    rgba(255, 255, 255, 0.88) 0%,
    rgba(255, 255, 255, 0.49) 100%
  );
  border-image: linear-gradient(
      180deg,
      rgba(255, 255, 255, 1),
      rgba(255, 255, 255, 0.38)
    )
    2 2;
}

.result-bar {
  width: 100%;
}

.comment-bar {
  text-align: right;
}

/* 动画 */
.prompt {
  width: 100%;
  height: 80px;
  position: fixed;
  bottom: 100px;
}

.prompt text {
  position: absolute;
  bottom: 2px;
  color: #f3a73f;
  left: calc(45%);
  animation: puls 1.5s infinite ease-in-out;
}

.dots-container {
  display: flex;
  align-items: center;
  justify-content: center;
  height: 80px;
  width: 45%;
  position: absolute;
  bottom: 0px;
  left: calc(27.5%);
  background-color: #fdedd9;
  border-radius: 20px;
}

.dot {
  height: 16px;
  width: 16px;
  margin-right: 10px;
  border-radius: 10px;
  background-color: #f3a73f;
  animation: pulse 1.5s infinite ease-in-out;
}

.dot:last-child {
  margin-right: 0;
}

.dot:nth-child(1) {
  animation-delay: -0.3s;
}

.dot:nth-child(2) {
  animation-delay: -0.1s;
}

.dot:nth-child(3) {
  animation-delay: 0.1s;
}

@keyframes pulse {
  0% {
    transform: scale(0.8);
    background-color: #f3a73f;
    box-shadow: 0 0 0 0 rgba(243, 167, 63, 0.7);
  }

  50% {
    transform: scale(1.2);
    background-color: #f9d39f;
    box-shadow: 0 0 0 10px rgba(178, 212, 252, 0);
  }

  100% {
    transform: scale(0.8);
    background-color: #f3a73f;
    box-shadow: 0 0 0 0 rgba(243, 167, 63, 0.7);
  }
}

@keyframes puls {
  0% {
    transform: translateY(0px);
  }

  50% {
    transform: translateY(-4px);
  }

  100% {
    transform: translateY(0px);
  }
}
</style>
